#include <vector>

class UnionFindSet{
  const int N;
  int cnt;
  std::vector<int> id, sz;
public:
  UnionFindSet(int n) : N(n), cnt(N), id(N), sz(N){
    for(int i = 0; i < N; ++i){
      id[i] = i;
      sz[i] = 1;
    }
  }
  int find_id(int x){
    return id[x] == x ? x : (id[x] = find_id(id[x]));
  }
  bool union_set(int a, int b){
    int i = find_id(a), j = find_id(b);
    if(i == j){
      return false;
    }
    if(sz[i] < sz[j]){ id[i] = j; sz[j] += sz[i]; }
    else             { id[j] = i; sz[i] += sz[j]; }
    --cnt;
    return true;
  }
  int count() const {
    return cnt;
  }
};

#include <iostream>
#include <vector>
using namespace std;

/* HDOJ-1272 小希的迷宫
任意两个房间有且仅有一条路径可以相通。
最后是棵树。用并查集判断，每次合并都应当成功，否则两点都已在同一集合，就是有环。
任两个房间都必须连通：树有T个点T-1条边。
如有m个房间，应合并m-1个集合。但没有房间时合并0个集合（而不是-1）。
*/

int main(){
  const int N = 100001;
  while(1){
    bool y = true;
    UnionFindSet ufs(N);
    vector<int> room(N);
    for(int a, b, room_cnt = 0;;){
      cin >> a >> b;
      if(a < 0 || b < 0){
        return 0;
      }
      if(a == 0 || b == 0){
        int merged = (room_cnt ? room_cnt - 1 : 0);
        cout << (y && ufs.count() + merged == N ? "Yes" : "No") << endl;
        break;
      }
      if(room[a] == 0){ room[a] = 1; ++room_cnt; }
      if(room[b] == 0){ room[b] = 1; ++room_cnt; }
      if(!ufs.union_set(a, b)){
        y = false;
      }
    }
  }
}